package com.vita.testCore.value;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * ValueStore 可以自动根据 input、output内容输出 CvtValue<I,O> 或 CvtList<I,O>
 */
public class ValueStore<I,O> implements CvtMetaInfo{
    private final static String KEY = "ValueStore";
    private String id;

    /**
     * value和valueList只能有一个处于激活状态
     * 非激活状态 value = null 、 valueList = null
     */
    private CvtValue<I,O> value;
    private CvtList<I,O> valueList;

    {
        id = UUID.randomUUID().toString().replaceAll("-","");
    }

    public ValueStore(){}

    public ValueStore(I i){
        this.value = new CvtValue<>(i);
    }

    public ValueStore(I i,O o){
       this.value = new CvtValue<>(i,o);
    }

    public void setInput(I i){
        if (valueListIsLive()){
            this.valueList.input(i);
        }else{
            this.value.input(i);
        }
    }

    public void setOutput(O o){
        if (valueListIsLive()){
            this.valueList.output(o);
        }else{
            if(value == null){
                throw new ClassCastException("input数值缺省");
            }else {
                this.value.output(o);
            }
        }
    }

    /**
     * 入值
     */
    public void inValue(I i,O o){
        if (valueIsLive()) {
            valueLive(i, o);
        } else {
            listLive(i, o);
        }
    }

    /**
     * 获取值
     */
    public void getValue(){}

    /**
     * 激活value
     */
    private void valueLive(I i,O o){
        this.value = new CvtValue<>(i,o);
    }

    /**
     * 激活listValue
     */
    private void listLive(I i,O o){

        if (value == null) return;
        if (valueList != null) return;

        List<I> inputs = new ArrayList<>();
        List<O> outputs = new ArrayList<>();
        inputs.add(this.value.getInput());
        outputs.add(this.value.getOutput());
        inputs.add(i);
        outputs.add(o);

        this.valueList = new CvtList<>(inputs,outputs);
        this.value = null;
    }

    public void clear(){
        this.value = null;
        this.valueList = null;
    }


//    public <T> Flowable<T> onAssembly(Flowable<T> source){
//        return
//    }
//
//    static <T, R> R apply(Function<T, R> f, T t) {
//        try {
//            return f.apply(t);
//        } catch (Throwable ex) {
//            throw ExceptionHelper.wrapOrThrow(ex);
//        }
//    }

    private boolean valueIsLive(){ return this.valueList == null; }

    private boolean valueListIsLive(){
        return this.valueList != null;
    }


    @Override
    public String getKey() {
        return KEY;
    }

    @Override
    public String getId() {
        return id;
    }


}
